package com.galaxis.wms.security.handler;

import com.galaxis.wms.EnumConstant;
import com.yvan.core.SystemClock;
import com.yvan.data.redis.Redis;
import com.yvan.security.SecurityDataSource;
import com.yvan.security.config.RedisConfig;
import com.yvan.security.config.SecurityConfig;
import com.yvan.security.handler.LogoutSuccessHandler;
import com.yvan.security.model.UserInfo;
import com.yvan.security.model.event.LogoutSuccessEvent;
import com.yvan.security.utils.SecurityRedisKey;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;

import static com.galaxis.wms.query.QSysJwtToken.sysJwtToken;

/**
 * 作者：lizw <br/>
 * 创建时间：2020/12/14 21:33 <br/>
 */
@Slf4j
public class DefaultLogoutSuccessHandler implements LogoutSuccessHandler {
    private final SecurityConfig securityConfig;

    public DefaultLogoutSuccessHandler(SecurityConfig securityConfig) {
        this.securityConfig = securityConfig;
    }

    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, LogoutSuccessEvent event) {
        // 禁用JWT-Token
        SecurityDataSource.getJdbc().beginTX(status -> {
            disableJwtToken(event.getClaims());
            return null;
        });
        // 从Redis中删除SysJwtToken
        final RedisConfig redis = securityConfig.getRedis();
        if (redis.isEnable()) {
            UserInfo userInfo = event.getSecurityContext().getUserInfo();
            SecurityDataSource.getRedis().kExpire(
                    SecurityRedisKey.getTokenKey(redis.getRedisNamespace(), userInfo.getUserId(), event.getClaims().getId()),
                    Redis.DEL_TIME_OUT
            );
        }
    }

    protected void disableJwtToken(Claims claims) {
        SecurityDataSource.getQueryDSL().update(sysJwtToken)
                .set(sysJwtToken.disable, EnumConstant.DISABLE_1)
                .set(sysJwtToken.disableReason, EnumConstant.JWT_TOKEN_DISABLE_REASON_3)
                .set(sysJwtToken.updateAt, new Timestamp(SystemClock.now()))
                .where(sysJwtToken.id.eq(Long.parseLong(claims.getId())))
                .execute();
        log.debug("### 登出成功 -> userId={} | token id={}", claims.getSubject(), claims.getId());
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
